package org.classdef.scan.print;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.classdef.analyzer.info.ClassDef;

public class FileResultPrinter implements IResultPrinter {
	
	protected ThreadPoolExecutor executor = new ThreadPoolExecutor(0, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
	protected File file;
	protected IPrintFormater formater;
	protected LinkedList<ClassDef> classDefList;
	
	public FileResultPrinter(String output){
		this(output, null);
	}

	public FileResultPrinter(String output, IPrintFormater formater) {
		File file = null;
		File tmpFile = new File(output);
		if(tmpFile.exists()){
			if(tmpFile.isDirectory()){
				file = new File(tmpFile.getPath() + File.separator + "result.data");
				try {
					file.createNewFile();
				} catch (IOException e) {
					file = null;
				}
			}else {
				file = tmpFile;
				try {
					file.delete();
					file.createNewFile();
				} catch (IOException e) {
					file = null;
				}
			}
		}else {
			if(tmpFile.getName().contains(".")){
				if(!tmpFile.getParentFile().exists()){
					tmpFile.getParentFile().mkdirs();
				}
				try {
					if(tmpFile.createNewFile()){
						file = tmpFile;
					}
				} catch (IOException e) {
				}
			}else {
				tmpFile.mkdirs();
				file = new File(tmpFile.getPath() + File.separator + "result.data");
				try {
					file.createNewFile();
				} catch (IOException e) {
					file = null;
				}
			}
		}
		if(file != null){
			this.file = file;
		}
		this.formater = formater;
	}
	
	@Override
	public void start() {
		classDefList = new LinkedList<ClassDef>();
	}

	@Override
	public void stop() {
		executor.execute(new Runnable(){

			@Override
			public void run() {
				BufferedWriter printer = null;
				try {
					printer = new BufferedWriter( new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8"));
					for (ClassDef classDef : classDefList) {
						String msg = getOut(classDef);
						if(msg != null && !"".equals(msg)){
							printer.write(msg + "\r\n");
						}
					}
					printer.flush();
				} catch (IOException e) {
				}finally {
					if(printer != null){
						try {
							printer.close();
						} catch (IOException e) {
						}
					}
				}
			}
			
		});
	}

	@Override
	public void print(ClassDef info) {
		if(this.file != null){
			classDefList.add(info);
		}
	}
	
	private String getOut(ClassDef info){
		if(this.formater != null){
			return this.formater.format(info);
		}
		return info.toString();
	}

}
